package org.six11.ss.client;

import java.util.StringTokenizer;

import org.six11.ss.shared.Message;
import org.six11.util.Debug;
import org.six11.util.adt.MultiState;
import org.six11.util.adt.SynchronizedQueue;

/**
 * An abstract base class for all 'commands' on the client in Stellasketch. These commands may be
 * typed in (which invokes handleCommand(String)), or they may originate from some other user action
 * (which invokes handleCommand(Message)), like clicking on a button.
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public class CommandHandler {

  protected MultiState state;

  public CommandHandler(MultiState state) {
    this.state = state;
  }

  /**
   * This is the function that should be implemented by command-line handlers, which should generate
   * a Message object and then use sendMessage.
   * 
   * The argument is optional, and is reserved for use by the TextConsole's "slash-command".
   * 
   * @param args
   *          an optional string, formatted in whichever way makes sense for the command.
   */
  public void handleCommand(String args) {
    bug("null implementation of handleCommand called!");
  }

  /**
   * Parses the argument string for key=value pairs, and uses 'msg.addParam(key, value)'.
   * 
   * @param msg
   *          The message in which key/val pairs will be set.
   * @param args
   *          An unparsed command string, which is possibly of zero length, but should not be null.
   */
  protected void setParams(Message msg, String args) {
    StringTokenizer toks = new StringTokenizer(args, " ");
    while (toks.hasMoreTokens()) {
      StringTokenizer eqToks = new StringTokenizer(toks.nextToken(), "=");
      String key = eqToks.nextToken();
      String val = eqToks.nextToken();
      bug("key/val: " + key + " = " + val);
      msg.addParam(key, val);
    }
  }

  @SuppressWarnings("unchecked")
  protected void sendMessage(Message msg) {
    SynchronizedQueue<Message> q = (SynchronizedQueue<Message>) state
        .getValue(ClientStateNames.K_TRANSMIT_QUEUE);
    q.add(msg);
  }

  @SuppressWarnings("unchecked")
  public SynchronizedQueue<Message> getQueue() {
    return (SynchronizedQueue<Message>) state.getValue(ClientStateNames.K_TRANSMIT_QUEUE);
  }

  protected void bug(String what) {
    String n = getClass().getName();
    Debug.out(n.substring(n.lastIndexOf('.') + 1), what);
  }
}
